package com.zt.english.service

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.media.AudioAttributes
import android.media.AudioFocusRequest
import android.media.AudioManager
import android.os.Build
import android.os.Handler
import android.os.IBinder
import android.os.PowerManager
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.core.app.NotificationCompat
import com.zt.english.R
import com.zt.english.player.AudioPlayerController
import java.util.*

/**
 * 音频播放服务类保活方案：
 * 将Service置为前台，目的时提高进程Service的oom_adj值，以降低其被系统回收的几率。该方案的原理是
 * ，通过使用 startForeground()方法将当前Service置于前台来提高Service的优先级。需要注意的是，
 * 对API大于18而言 startForeground()方法需要弹出一个可见通知，如果你觉得不爽，可以开启另一个Service将通知栏移除，
 * 其oom_adj值还是没变的
 */
class AudioService :Service(){

    private var mWakeLock: PowerManager.WakeLock? = null

    private lateinit var audioPlayerController:AudioPlayerController
    init {
        audioPlayerController = AudioPlayerController.get()
    }
    companion object{
        public val NOTICE_ID :Int = 1
    }

    override fun onBind(p0: Intent?): IBinder? {
        System.out.println("MusicService-onBind()")
        return null
    }

    override fun onCreate() {
        super.onCreate()
        System.out.println("MusicService-onCreate()")
        getLock(this)

        //通过使用 startForeground()方法将当前Service置于前台来提高Service的优先级,实现service保活
        //如果API大于18，需要弹出一个可见通知
        val builder = NotificationCompat.Builder(this,"chanid")
        builder.setSmallIcon(R.mipmap.ic_launcher)
        builder.setContentTitle("KeepAppAlive")
        builder.setContentText("AudioService is runing...")

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            //修改安卓8.1以上系统报错
            val notificationChannel = NotificationChannel("chanid", "chan", NotificationManager.IMPORTANCE_MIN)
            notificationChannel.enableLights(true) //如果使用中的设备支持通知灯，则说明此通知通道是否应显示灯
            notificationChannel.setShowBadge(true) //是否显示角标
            notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET)

            val manager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            manager.createNotificationChannel(notificationChannel)
        }
        builder.setAutoCancel(true)

        startForeground(NOTICE_ID, builder.build())

        // 如果觉得常驻通知栏体验不好
        // 可以通过启动CancelNoticeService，将通知移除，oom_adj值不变
        val intent = Intent(this, CancelNoticeService::class.java)
        startService(intent)
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        System.out.println("MusicService-onStartCommand()")
        val url = intent?.getStringExtra("url")
        audioPlayerController.prepareAudioData(url!!)
        return START_STICKY
    }


    override fun onDestroy() {
        super.onDestroy()
        System.out.println("MusicService-onDestroy()")
        //停在播放
        audioPlayerController.destory()
        releaseLock()

        // 如果Service被杀死，干掉通知
        val mManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        mManager.cancel(NOTICE_ID)

        // 重启自己
        val intent = Intent(applicationContext, AudioService::class.java)
        startService(intent)
    }

    //保证息屏后不被释放资源杀死（WakeLock的使用)
    /**
     * 同步方法   得到休眠锁
     * @param context
     * @return
     */
    @Synchronized
    private fun getLock(context: Context) {
        if (mWakeLock == null) {
            val mgr = context.getSystemService(Context.POWER_SERVICE) as PowerManager
            mWakeLock = mgr.newWakeLock(
                PowerManager.PARTIAL_WAKE_LOCK,
                AudioService::class.java.getName()
            )
            mWakeLock?.setReferenceCounted(true)
            val c: Calendar = Calendar.getInstance()
            c.setTimeInMillis(System.currentTimeMillis())
            val hour: Int = c.get(Calendar.HOUR_OF_DAY)
            if (hour >= 23 || hour <= 6) {
                mWakeLock?.acquire(5000)
            } else {
                mWakeLock?.acquire(300000)
            }
        }
    }
    /**
     * 释放锁的方法（避免占用内存）
     */
    @Synchronized
    private fun releaseLock() {
        if (mWakeLock != null) {
            if (mWakeLock?.isHeld!!) {
                mWakeLock?.release()
            }
            mWakeLock = null
        }
    }
}